home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / iritsm3s.zip / INTRNRML.C < prev    next >
C/C++ Source or Header  |  1991-11-10  |  5KB  |  153 lines

  1. /*****************************************************************************
  2. *   "Irit" - the 3d polygonal solid modeller.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.2, Aug. 1990   *
  5. ******************************************************************************
  6. *   Module to interplate internal vertices using vertices on the given       *
  7. * convex boundary OriginalVList. All internal vertices are assumed to be in  *
  8. * the interior of the convex region defined by OriginalVList or on its       *
  9. * boundary.                                     *
  10. *****************************************************************************/
  11.  
  12. #include <math.h>
  13. #include "program.h"
  14. #include "geomat3d.h"
  15. #include "intrnrml.h"
  16.  
  17. /* #define DEBUG           To define polygon (with normals printing routine. */
  18.  
  19. static void UpdateOneVertexNormal(VertexStruct *VUpdate,
  20.                   PolygonStruct *OriginalPl);
  21.  
  22. #ifdef DEBUG 
  23. static void PrintPolygon(PolygonStruct *Pl);
  24. #endif /* DEBUG */
  25.  
  26. /*****************************************************************************
  27. *   For each polygon in PlList update any vertex normal which is zero to an  *
  28. *interpolated value using the Original polygon vertex list OriginalVList.    *
  29. *   All the new vertices are enclosed within the original polygon which      *
  30. * must be convex as well.                             *
  31. *****************************************************************************/
  32. void UpdateVerticesNormals(PolygonStruct *PlList, PolygonStruct *OriginalPl)
  33. {
  34.     VertexStruct *V, *VHead;
  35.  
  36.     while (PlList) {
  37.     V = VHead = PlList -> V;
  38.     do {
  39.         if (APX_EQ(V -> Normal[0], 0.0) &&
  40.         APX_EQ(V -> Normal[1], 0.0) &&
  41.         APX_EQ(V -> Normal[2], 0.0)) {
  42.         /* This vertex need to be updated. */
  43.         UpdateOneVertexNormal(V, OriginalPl);
  44.         }
  45.  
  46.         V = V -> Pnext;
  47.     }
  48.     while (V != NULL && V != VHead);
  49.  
  50.     PlList = PlList -> Pnext;
  51.     }
  52. }
  53.  
  54. /*****************************************************************************
  55. *   Update one vertex normal be a convex blend of boundary vertices normals  *
  56. *****************************************************************************/
  57. static void UpdateOneVertexNormal(VertexStruct *VUpdate,
  58.                   PolygonStruct *OriginalPl)
  59. {
  60.     VertexStruct *V, *OriginalVList = OriginalPl -> V;
  61.  
  62.     V = OriginalVList;
  63.     do {
  64.     if (Colinear3Vertices(V, VUpdate, V -> Pnext)) {
  65.         /* Interpolate the normal according to the edge vertices VUpdate */
  66.         /* is on and according to the distance of VUpdate to edge ends.  */
  67.         InterpNrmlBetweenTwo(VUpdate, V, V -> Pnext);
  68.         return;
  69.     }
  70.     V = V -> Pnext;
  71.     }
  72.     while (V != NULL && V != OriginalVList);
  73.  
  74.     /* If we are here then the point is not on the polygon boundary and in   */
  75.     /* that case we simply use the polygon normal as an approximation.       */
  76.     PT_COPY(VUpdate -> Normal, OriginalPl -> Plane);
  77. }
  78.  
  79. /*****************************************************************************
  80. *   Returns TRUE iff the 3 vertices are colinear.                 *
  81. *****************************************************************************/
  82. int Colinear3Vertices(VertexStruct *V1, VertexStruct *V2, VertexStruct *V3)
  83. {
  84.     RealType l;
  85.     VectorType V12, V23, V;
  86.  
  87.     if (PT_EQ(V1 -> Pt, V2 -> Pt) || PT_EQ(V2 -> Pt, V3 -> Pt))
  88.     return TRUE;
  89.  
  90.     PT_SUB(V12, V1 -> Pt, V2 -> Pt);
  91.     PT_SUB(V23, V2 -> Pt, V3 -> Pt);
  92.  
  93.     /* Make sure the middle point is in fact in the middle. */
  94.     if (V12[0] * V23[0] < -EPSILON ||
  95.         V12[1] * V23[1] < -EPSILON ||
  96.     V12[2] * V23[2] < -EPSILON)
  97.     return FALSE;
  98.  
  99.     VecCrossProd(V, V12, V23);
  100.  
  101.     l = PT_LENGTH(V);
  102.  
  103.     return APX_EQ(l, 0.0);
  104. }
  105.  
  106.  
  107. /*****************************************************************************
  108. *   Returns TRUE iff the 3 vertices are colinear.                 *
  109. *****************************************************************************/
  110. void InterpNrmlBetweenTwo(VertexStruct *V, VertexStruct *V1, VertexStruct *V2)
  111. {
  112.     RealType t1, t2;
  113.     VectorType Vec1, Vec2;
  114.  
  115.     PT_SUB(Vec1, V -> Pt, V1 -> Pt);
  116.     PT_SUB(Vec2, V -> Pt, V2 -> Pt);
  117.     t1 = PT_LENGTH(Vec1);
  118.     t2 = PT_LENGTH(Vec2);
  119.  
  120.     PT_COPY(Vec1, V1 -> Normal);
  121.     PT_COPY(Vec2, V2 -> Normal);
  122.     PT_SCALE(Vec1, t2);
  123.     PT_SCALE(Vec2, t1);
  124.     PT_ADD(V -> Normal, Vec1, Vec2);
  125.  
  126.     PT_NORMALIZE(V -> Normal);
  127. }
  128.  
  129. #ifdef DEBUG 
  130.  
  131. /*****************************************************************************
  132. *   Print the content of the given polygon, to standard output.             *
  133. *****************************************************************************/
  134. static void PrintPolygon(PolygonStruct *Pl)
  135. {
  136.     VertexStruct *V = Pl -> V,
  137.          *VHead = V;
  138.  
  139.     do {
  140.     printf("    %10lg %10lg %10lg (%10lg %10lg %10lg)",
  141.            V -> Pt[0], V -> Pt[1], V -> Pt[2],
  142.            V -> Normal[0], V -> Normal[1], V -> Normal[2]);
  143.     if (IS_INTERNAL_EDGE(V))
  144.         printf(" (Internal)\n");
  145.     else
  146.         printf("\n");
  147.     V = V -> Pnext;
  148.     }
  149.     while (V!= NULL && V != VHead);
  150. }
  151.  
  152. #endif /* DEBUG */
  153.